/**
 * project6
 *
 * brief description of the program
 *
 * This program is released to public domain according to
 * author's wish, you can view full license at
 * http://tomatoeskit.org/upload/PublicDomainLicense.txt
 *
 * @author Fangning CHENG (Alpha.L Cheng) <chengf@purdue.edu>
 *
 * @lab section number 
 *
 * @date Oct 24, 2013
 *
 */
import java.util.LinkedList;
import java.util.Queue;
import edu.purdue.cs.cs180.channel.*;

public class Server implements MessageListener {
    Channel          channel;
    Queue<EndPointInfo> requesters = new LinkedList<EndPointInfo>();
    Queue<EndPointInfo> volunteers = new LinkedList<EndPointInfo>();

    Server (Channel cnl)
    {
        channel = cnl;
        channel.setMessageListener(this);
    }
    
    private class EndPointInfo {
        String info;
        int    clientID;

        EndPointInfo(String info, int clientID) {
            this.info = info;   // VolunteerID for volunteer, Building name for requester
            this.clientID = clientID;
        }
    }
    
    @Override
    public void messageReceived(String message, int clientID) {       
        String msg[] = message.split("\\s+");
        int msgLen = msg.length;

        // Invalid message
        if (msgLen < 2)
            return;

        // Request message
        if (msg[0].equals("REQUEST")) {
            requesters.offer(new EndPointInfo(msg[1], clientID));
        }

        // Volunteer message
        if (msg[0].equals("VOLUNTEER")) {
            volunteers.offer(new EndPointInfo(msg[1], clientID));
        }

        // Process the queue
        processQueue();
    }

    private void processQueue() {
        int loopCount = volunteers.size() < requesters.size() ? volunteers.size() : requesters.size();
        // Redundant, provides flexibility in case code changes in later days.
        
        for (int i = 0; i < loopCount; ++i) {
            EndPointInfo requesterInfo = requesters.poll();
            EndPointInfo volunteerInfo = volunteers.poll();
            try {
                // Send message to volunteer
                channel.sendMessage("LOCATION " + requesterInfo.info, volunteerInfo.clientID);
                // Send message to requester
                channel.sendMessage("VOLUNTEER " + volunteerInfo.info, requesterInfo.clientID);
            } catch (ChannelException e) {
                System.out.println(e.getMessage());
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        int port;

        if (args.length > 0) {
            if (args[0].equals("help")) {
                System.out.println("Usage: java Server port");
                System.out.println("Run project 6 server");
                System.out.println("port must be in the range from 1024 to 65535");
                return;
            }
            else {
                try {
                    port = Integer.parseInt(args[0]);
                } catch (Exception ex) {
                    System.out.println("Invalid port");
                    return;
                }
                if (port < 1024 || port > 65535) {
                    System.out.println("Invalid port");
                    return;
                }
            }
        } else {
            System.out.println("Server: missing file operand");
            System.out.println("Try `java Server help' for more information.");
            return;
        }
        
        @SuppressWarnings("unused")
        Server server = new Server(new TCPChannel(port));
    }
}


